Verifiable Builds
Checking Whonix for backdoors.
Manual Builds vs Build Script Builds[edit]
In oversimplified terms, Whonix is just a collection of configuration files and scripts.
- Manual Builds: One could start with Debian (or any Linux distribution) then use mice and keyboard to re-configure it to become something similar to Whonix.
- Build Script Builds: Such builds are created using a build script without any manual developer modifications as soon as the build script was started. All source code has been published prior or running the build script. All steps required such as building packages and creating a binary image are done automated by a build script.
Only build script builds are permitted for redistribution as per Whonix policy.
Redistribution of manual builds would be unprofessional.
Advantages of script created builds are that these are "cleaner". For a list of advantages, see this chapter.
Verifiable Builds[edit]
Verifiable .ova's[edit]
Introduction - What this Achieves[edit]
Whonix previously had a feature which allows the community to check that Whonix .ova [1] releases are verifiably created from the project's own source code - verifiable builds. [2] This only proves that the person and machine [3] building Whonix have not added anything malicious, such as a backdoor. [4] It does not prove there are no backdoors present in Debian. This is not possible, because neither Debian [5] nor any other operating system provides deterministic builds yet. [6]
This feature does not attempt to prove there are not any vulnerabilities present [7] in Whonix or Debian. Fatal outcomes are still possible via a remotely exploitable [8] bug in Whonix or Debian, a flaw in Whonix's firewall which leaks traffic, or code phoning home [9] the contents of the HDD/SSD. Community effort is a precondition to improved security with this feature, particularly auditing of Whonix and Debian source code to check for possible backdoors and vulnerabilities.
In summary, this feature is useful and potentially improves security, but it is not a magical solution for all computer security and trust issues. The following table helps to explain what this feature can achieve.
Table: Verifiable Builds Comparison
Whonix | Tails | Tor Browser | Qubes OS TorVM | corridor | |
Deterministic builds [10] | No | No (planned) [11] | Yes [12] | No | Not applicable [13] |
Based on a deterministically built [10] operating system | No [14] | No [14] | Not applicable | No [14] | No [14] |
Verifiably no backdoor in the project's own source code | Invalid [15] | Invalid [15] | Invalid [15] | Invalid [15] | Invalid [15] |
Verifiably vulnerability-free | No [16] | No [16] | No [16] | No [16] | No [16] |
Verifiably no hidden source code [17] in upstream distribution / binaries [18] | No [19] | No [19] | No [19] | No [19] | No [19] |
Project's binary builds are verifiably created from project's own source code (no hidden source code [17] in the project's own source code) | No (deprecated) [20] | No | Yes | No | Not applicable [13] |
Some readers might be curious why Whonix was previously verifiable, while Debian and other distributions are not. In short, this is because Whonix is uncomplicated by comparison. In simple terms, Whonix is a collection of configuration files and scripts, and the source code does not contain any compiled code and so on. In contrast, Debian is a full operating system, without which Whonix would not exist. [21]
This feature was first made available in Whonix 8. Only users who download a new image can profit from this feature. [22] It is not possible to audit versions older than Whonix 8 with this script. [23]
Short Overview - How it Works[edit]
When building Whonix .ova's from source code, for example /home/user/whonix_binary/Whonix-Gateway-9.ova also report /home/user/whonix_binary/Whonix-Gateway-9.report file will be created.
After building the .ova, the last build-step will extract the .ova, which will result in getting three files, i.e. Whonix-Gateway-9.ovf, Whonix-Gateway-9.mf and Whonix-Gateway-9-disk1.vmdk. The .vmdk [24] image will then be converted to .vdi [25], then converted to raw [26] (.img. (Converting as in creating a copy, not actually converting.) The filesystem layout, the MBR [27] and the VBR [28] are written into separate files. The raw image will then be mounted. A sha512 checksum of every file will be created and stored in the report.
Anyone building Whonix.ova images will hopefully end up with the same report. We can then compare the reports using tools such as diff and/or meld. Those reports should be very similar. We can't end up with the very same reports, because again, there are no deterministically built operating systems yet. However, we can manually review the few remaining differences. That should make it reasonable to believe, that the original Whonix.ova images have been built from the source code that has been published for that Whonix version.
Below on this page is a longer How-To.
Current Limitations[edit]
During the build process of Whonix-Gateway™ we are still using torproject.org's Tor repository for Debian testing [29]. Should that version get upgraded, this will create differences. In theory, old files could still be verified against torproject's signing keys, but that would require them to be archived somewhere. There is currently no such archive. (Peter Palfrader offered to provide the old packages on request). Whonix is currently only easily verifiable as long as torproject.org's repository does not get upgraded. In future, when Tor 0.2.4 migrates into Debian testing, this limitation may be lifted. We're happy to hear better solutions in meanwhile.
Our help-steps/analyze_image script does not check the contents of the image outside the file system. We're not aware of any method getting a backdoor activated by writing malicious data into those places. We might get rid of this limitation in future, see chapter Possible Future Improvements.
We don't check GUID [30], because we're not using GUID. [31]
Attack Surface[edit]
The /help-steps/analyze_image script is supposed to execute no code from the image you are analyzing. The risk running that script on images you did not create yourself such as on the official images should be low, but not non-existent. Audits of the analyzing script itself are most welcome. In order to analyze the image, tools which are available in Debian's repository are used. Such as extracting the .ova requires tar[32]. In theory, the .ova could be malformed in a way to exploit the auditor's machine while extracting it to coerce the auditor's machine create a legit report hiding the actual backdoor (and infecting the auditor's machine with a backdoor). To find out what other tools are used and for what, please have a look at the /help-steps/analyze_image script.
Theoretical Holes[edit]
Unfortunately, we can not directly mount the .ova. We have to extract it first. Rather, VirtualBox does not support creating .ova containing .img (raw images). Img's would be ideal, since low level tools such as dd understand them. Even worse, .ova's created by VirtualBox always include .vmdk. export VM using VDI instead of VMDK is not possible. Rather Mounting VMDK's on Debian testing/bookworm using Free Software is currently not possible since no software supports that. During the convert process ova → vmdk → vdi → img, the MBR, bootloader, VBR and/or other obscure differences could occur. There is no reason to believe that is actually the case, but we're not aware of any research on that topic.
Your Own Alternatives[edit]
The /help-steps/analyze_image script is the tool which comes with Whonix source code to audit Whonix.ova. Nothing prevents you from cooking up your own custom method to verify Whonix.ova. On the contrary, we'd be very happy to hear about your methods, source code and results. Since this hasn't ever happened in past, Whonix came up with its own /help-steps/analyze_image script.
Possible Future Improvements[edit]
sleuthkit[edit]
sleuthkit could be an interesting addition or even replacement for Whonix custom script. Then something like this could perhaps be used.
mmls ~/whonix_binary/{{project_name_gateway_short}}-9.raw
fsstat -o 0000004096 ~/whonix_binary/{{project_name_gateway_short}}-9.raw
fls -r -o 0000004096 ~/whonix_binary/{{project_name_gateway_short}}-9.raw
tsk_gettimes ~/whonix_binary/{{project_name_gateway_short}}-9.raw
fiwalk ~/whonix_binary/{{project_name_gateway_short}}-9.raw
Do these tools produce very similar results when run on very similar images or does it mess up the ordering?
fiwalk unfortunately only supports md5 and sha1 and not yet SHA-256 and/or SHA-3.
Issue Tracker[edit]
https://phabricator.whonix.org/tag/verifiable_builds/
Expected Differences[edit]
- (mount_folder) /boot/initrd.img* - Those are extracted to the initrd_folder and diffed.
- (mount_folder) /etc/shadow - Manually look at the diff. Users are advised to change their passwords anyway.
- (mount_folder) /etc/shadow- - Same as above.
- (mount_folder) /etc/init.d/.depend.boot - /sbin/insserv (part of sysvinit) does not produce deterministic results. Gets copied to the manual_analysis_folder. Manually review them. You just have to check, they're not containing anything sketchy. You most likely won't be able to tell, if some services are deliberately not started or in wrong order. This is not an issue, because when Whonix starts for the first time it executes whonix_shared/usr/lib/whonix/first_run_initializer, which executes /sbin/insserv, which recreates this file. [34]
- (mount_folder) /etc/init.d/.depend.start - Same as above.
- (mount_folder) /etc/init.d/.depend.stop - Same as above.
- (mount_folder) /usr/share/whonix/build_timestamp - Timestamp, naturally differs.
- (mount_folder) /var/lib/initramfs-tools/... - Is a one-line text file, which contains the name of the initrd and its checksum. Differs, because the initrd is not deterministic in the first place.
- (mount_folder) /var/lib/initramfs-tools/... - Same as above.
Unexpected Differences[edit]
There could be differences besides the expected differences, because this is still experimental as in a new feature. Remember, there are no deterministically built distributions yet. If you find any additional differences, keep calm, it is not necessarily a backdoor, report them, and if you can, diff and/or audit them.
Folder Overview[edit]
Your report root folder can most likely be found in /home/user/whonix_binary/$VMNAME-${derivative-maker_whonix_version_new}_report_tempfolder.
extracted_ova_folder - Should contain 3 files. One .vmdk, which you can ignore, that's what we unpack - if we could diff it in the first place we wouldn't have so much trouble. Since the contents of the extracted_ova_folder gets added to the file_list, it won't be possible, that there are any extra files - if there were, you could see them in the report and should be suspicious.
vdi_folder - Should only contain one .vdi. If we could diff it in the first place we wouldn't have so much trouble.
raw_folder - Should only contain one .img. Same as above.
auto_hash_folder - Are all added to the .report and file_list and should contain no differences.
extracted_initrd_folder - The are the extracted (mount_folder) /boot/initrd.img* files. Are all added to the .report and file_list and should contain no differences.
manual_analysis_folder - Not hashed in the .report file, because those will show differences anyway which we expect. Those have to be manually audited.
debug_folder - We copy these files out of the images just in case for convenience. Those have been already checksum'ed (in the .report file) as regular files within the (mount_folder). Feel free to ignore that folder. It is only in for debugging purposes.
How-To[edit]
First of all, you need to create your own Whonix.ova images from source code, refer to Build Documentation. Your report file can most likely be found at /home/user/whonix_binary/$VMNAME-$derivative-maker_whonix_version_new.report and your report_tempfolder at /home/user/whonix_binary/$VMNAME-${derivative-maker_whonix_version_new}_tempfolder. That is your own analyzed .ova. To make space for another analysis for other builds (such as those from whonix.org), rename your whonix_binary folder to something else, such as whonix_binary1.
If you've built for example Whonix 9, you have to download Whonix 9 as well. Place the .ova in /home/user/whonix_binary/. Keep the original name. Then go to Whonix source code folder (cd /home/user/Whonix and analyze that image. Use.
## {{project_name_short}} 9 sudo ./build-steps.d/5100_create-report --tor-gateway ## {{project_name_short}} 13/14 sudo ./build-steps.d/5100_create-report --build --flavor whonix-gateway
(And later repeat that step with the --tor-workstation switch.)
Then you have two .report files and two report temp folders.
Use your favorite diff viewer for huge files. For example meld. Diff the reports. For example, use.
meld ./whonix_binary1/{{project_name_gateway_short}}-9.report ./whonix_binary/{{project_name_gateway_short}}-9.report
These files should be very similar, expect for a few differences which we earlier mentioned in chapter Expected Differences. Look at the differences. Two of them (because we're installing two kernels) should look like this:
(mount_folder) /boot/initrd.img...
Check at the top of your report files for (extracted_initrd_folder) and see if both initrd's were really extracted. [35]
Also ignore (mount_folder) /etc/init.d/.depend.boot, (mount_folder) /etc/init.d/.depend.start, and (mount_folder) /etc/init.d/.depend.stop for now, this is an expected difference and we audit them later.
Also ignore (mount_folder) /etc/shadow and (mount_folder) /etc/shadow- for now, this is an expected difference and we audit them later.
Also ignore (mount_folder) /usr/share/derivative-maker_timestamp for now, this is an expected difference and we audit them later.
Also ignore (mount_folder) /var/lib/initramfs-tools/... for now, this is an expected difference and we audit them later.
There should be no other differences in the .report files!
Now it is time to audit the differencing files which we ignored above.
Diff the virtual machine description file (extracted_ova_folder) *.ovf. Only the uuids should differ. (The extracted_ova_folder folder can be found in your report_temp folders.)
Diff the manifest file (extracted_ova_folder) *.mf. Only the checksums should differ.
Finally diff the rest of the files in your manual_analysis_folder. Using a diff application which can diff whole folders such as meld would be useful, but what tools you use is up to you. Have a look at the "Expected Differences" chapter above for the kind of differences you can expect.
Auditing these files is unfortunately a bit difficult. The best tip to be given is to use your common sense. For example, having two /etc/init.d/.depend.start files at same size, but different order is probably not a backdoor. But if there are a lot extra lines looking weird (unrelated example code), there might be something wrong.
Verifiable Whonix Debian Packages[edit]
This has been deprecated because it is difficult to implement before the experimental, Debian reproducible toolchain is merged into the stable release. [36]
Shouldn't they match, you could also compare them using debdiff or debbindiff.
We don't have a script yet to automate that process.
Implementation[edit]
In case you like to review the implementation, the related scripts can be found here:
- Remove most non-deterministic parts (auto generated files which always look at bit different): https://github.com/Kicksecure/initializer-dist/blob/master/usr/libexec/initializer-dist/chroot-scripts-post.d/80_cleanup
- Build step to create the report: https://github.com/Whonix/derivative-maker/blob/master/build-steps.d/5100_create-report
- The analyze image script, which creates the report: https://github.com/adrelanos/Whonix/blob/master/help-steps/analyze_image
- The user interface locally re-creating non-deterministic files when Whonix starts for the first time:
- Re-creating non-deterministic files when Whonix starts for the first time: todo
Discussion[edit]
Links[edit]
- https://reproducible-builds.org/contribute/debian/#Working_on_installation_media_or_live_systems
- Whonix Verifiable Builds Issue Tracker
Footnotes / References[edit]
[ Whonix 8 snapshot of this page]
- ↑ https://en.wikipedia.org/wiki/Open_Virtualization_Format
- ↑ This feature only adds security if people actually use it. Do not assume that someone else will do it for you
- ↑ Due to build machine compromise.
- ↑ https://en.wikipedia.org/wiki/Backdoor_(computing)
- ↑ Whonix is based on Debian.
- ↑ Some Debian developers are steadily working on this long-term project, see: Reproducible Builds.
- ↑ https://en.wikipedia.org/wiki/Vulnerability_(computing)
- ↑ https://en.wikipedia.org/wiki/Exploit_(computer_security)
- ↑ https://en.wikipedia.org/wiki/Phoning_home
- ↑ 10.0 10.1
Open Source software does not automatically prevent backdoors, unless the user creates their own binaries directly from the source code. People who compile, upload and distribute binaries (including the webhost) could add hidden code, without publishing the backdoor. Anybody can claim that a certain binary was built cleanly from source code, when it was in fact built using the source code with a hidden component. Those deciding to infect the build machine with a backdoor are in a privileged position; the distributor is unlikely to become aware of the subterfuge.
Deterministic builds can help to detect backdoors, since it can reproduce identical binary packages (byte-for-byte) from a given source. For more information on deterministic builds and why this is important, see:
- liberationtech mailing list: Deterministic builds and software trust.
- gitian.org
- As Mike Perry has observed: Current popular software development practices simply cannot survive targeted attacks of the scale and scope that we are seeing today. See: Deterministic Builds Part One: Cyberwar and Global Compromise.
- The Debian wiki tracking progress / development efforts to implement Reproducible Builds for all packages.
- ↑ See Tails Roadmap.
- ↑ See Deterministic Builds Part One: Cyberwar and Global Compromise and Deterministic Builds Part Two: Technical Details.
- ↑ 13.0 13.1 corridor only uses shell scripts.
- ↑ 14.0 14.1 14.2 14.3 To be fair, there are no deterministically built operating systems yet. It is a difficult process and takes a lot of effort to complete. While Debian has around 25,000 reproducible packages in mid-2021, this work has been ongoing since 2013 and is far from done.
- ↑ 15.0 15.1 15.2 15.3 15.4
The first form of backdoor is a vulnerability (bug) in the source code. Vulnerabilities are introduced either purposefully or accidentally due to human error. Following software deployment, an attacker may discover the vulnerability and use an exploit to gain unauthorized access. Such vulnerabilities can be cleverly planted in plain sight in open source code, while being very difficult to spot by code auditors. Examples of this type of backdoor include:
- An attempt to backdoor the kernel.
- The Debian SSL debacle; many argued that this wasn't a bug but in fact a backdoor, as it hadn't been spotted for several years.
It is therefore impossible to claim that non-trivial source code is backdoor-free, because backdoors can be hidden as vulnerabilities. Auditors scrutinizing the source code can only state an opinion about the quality of the source code, and eventually report vulnerabilities if/when they are identified. Assertions that source code is free of computer viruses (like trojan horses) is the only reasonable assertion that can be made. - ↑ 16.0 16.1 16.2 16.3 16.4 Although theoretically possible, there are no mathematically proven bug-free operating systems yet.
- ↑ The upstream distribution is the distribution on which the project is based. Whonix and Tails are based on Debian, thus Debian is their upstream distribution. QubesOS TorVM is based on Qubes OS, which is itself based on Fedora and Xen.
- ↑ See verifiable builds.
- ↑ Whonix relies on the tireless efforts of Debian and other upstream projects.
- ↑ Because in order to implement the verifiable builds feature, a lot of non-deterministic, auto-generated files are removed at the end of the build process and re-created during first boot.
- ↑ It is not actually impossible, but it would require significant effort.
- ↑ https://en.wikipedia.org/wiki/VMDK
- ↑ https://en.wikipedia.org/wiki/VDI_(file_format)
- ↑ https://en.wikipedia.org/wiki/Raw_image_format
- ↑ https://en.wikipedia.org/wiki/Master_boot_record
- ↑ https://en.wikipedia.org/wiki/Volume_boot_record
- ↑ https://deb.torproject.org/torproject.org/dists/testing/main/binary-i386/Packages
- ↑ https://en.wikipedia.org/wiki/GUID_Partition_Table
- ↑ You can verify that by auditing Whonix source code.
- ↑ https://packages.debian.org/bookworm/tar
- ↑ (Solved!) fls / fstat issue: Invalid magic value (not an EXTxFS file system (magic))
- ↑ We can not delete this file before redistributing Whonix, because then Whonix wouldn't start.
- ↑ They should, because otherwise if extraction failed, the analyze_image script should have failed earlier and informed you already.
- ↑ Old advice: Since Whonix 7.5.2, all Whonix Debian Packages have been deterministically built. This means if the Whonix Debian Packages 7.5.2 are built from source code, and 7.5.2 downloaded from the Whonix Debian repository, it is possible to diff the checksum (for example the sha512sum) of those files and they should match. This has been deprecated because of a dpkg bug. The estimate of the Installed-Size can be wrong by a factor of 8, or a difference of 100MB (note: this bug has now been resolved). Different underlying file systems cause different file sizes, leading to checksums not matching.
We believe security software like Whonix needs to remain open source and independent. Would you help sustain and grow the project? Learn more about our 12 year success story and maybe DONATE!